package com.github.livebase.util.template;

import android.util.ArrayMap;
import android.util.ArraySet;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.github.livebase.util.base.ArraysUtil;
import com.github.livebase.util.base.CollectionsUtil;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @ClassName ArrayMapContext
 * @description:
 * @author: biao532
 * @create: 2023-12-27 23:27
 * @Version 1.0
 **/
public class CompositeMap<T,V> implements Map<T, V> {
    private List<Map<T, V>> list;
    public CompositeMap() {
        this(0);
    }
    public CompositeMap(int c) {
        list = new ArrayList<>(c+1);
        list.add(new ArrayMap<>(0));
    }

    public void add(Map<T, V> map) {
        list.add(map);
    }

    @Override
    public int size() {
        int size = 0;
        for (Map<T, V> m : list) {
            size += m.size();
        }
        return size;
    }

    @Override
    public boolean isEmpty() {
        return size() == 0;
    }

    @Override
    public boolean containsKey(@Nullable Object key) {
        return CollectionsUtil.first(list, (m) -> m.containsKey(key)) != null;
    }

    @Override
    public boolean containsValue(@Nullable Object value) {
        return CollectionsUtil.first(list, (m) -> m.containsValue(value)) != null;
    }

    @Nullable
    @Override
    public V get(@Nullable Object key) {
        for (Map<T, V> m : list) {
            if (m.containsKey(key)) {
                return m.get(key);
            }
        }
        return null;
    }

    @Nullable
    @Override
    public V put(T key, V value) {
        return list.get(0).put(key, value);
    }

    @Nullable
    @Override
    public V remove(@Nullable Object key) {
        return list.get(0).remove(key);
    }

    @Override
    public void putAll(@NonNull Map<? extends T, ? extends V> m) {
        list.get(0).putAll(m);
    }

    @Override
    public void clear() {
        list.clear();
    }

    @NonNull
    @Override
    public Set<T> keySet() {
        Set<T> set = new ArraySet<>(this.size());
        for (Map<T, V> m : list) {
            set.addAll(m.keySet());
        }
        return set;
    }

    @NonNull
    @Override
    public Collection<V> values() {
        Set<V> set = new ArraySet<>(this.size());
        for (Map<T, V> m : list) {
            set.addAll(m.values());
        }
        return set;
    }

    @NonNull
    @Override
    public Set<Entry<T, V>> entrySet() {
        Set<Entry<T, V>> set = new ArraySet<>(this.size());
        for (Map<T, V> m : list) {
            set.addAll(m.entrySet());
        }
        return set;
    }


    public void addMap(Map<T, V>... maps) {
        ArraysUtil.foreach(maps, (map) -> {
            if (list.contains(map)) {
                return;
            }
            list.add(map);
        });
    }


}
